﻿using System;
using System.Collections.Generic;
namespace Host
{
    public class Host
    {
        private Dictionary<string, IComponents> components_maping = new Dictionary<string, IComponents>();
        private List<IComponents> update_list = new List<IComponents>();

        public Host()
        {
            HostKey = new Random().Next().GetHashCode().ToString();
        }

        /// <summary>
        /// 托管的名称
        /// </summary>
        public string HostName { get; set; }

        /// <summary>
        /// 托管器的唯一Key
        /// </summary>
        public string HostKey { get; private set; }

        /// <summary>
        /// 销毁内容
        /// </summary>
        /// <value><c>true</c> if destroy me; otherwise, <c>false</c>.</value>
        public bool DestroyMe { get; set; }

        /// <summary>
        /// 更新
        /// </summary>
        public void Update()
        {
            foreach (var item in update_list)
            {
                if (item.NextRunTime * IComponents.TICK2SECOND < DateTime.Now.Ticks)
                {
                    item.Update();
                }
            }

            for (int i = update_list.Count - 1; i >= 0; --i)
            {
                var item = update_list[i];
                if (item.DestroyMe)
                {
                    item.OnRemove();
                    update_list.RemoveAt(i);
                }
            }
        }

        /// <summary>
        /// 进入业务逻辑
        /// </summary>
        public void OnEnter()
        {
            foreach (var item in components_maping)
            {
                item.Value.OnEnter();
            }

            foreach (var item in components_maping)
            {
                item.Value.OnEnterEnd();
            }
        }

        /// <summary>
        /// 退出业务逻辑
        /// </summary>
        public void OnExit()
        {
            foreach (var item in components_maping)
            {
                item.Value.OnExit();
            }

            ClearAll();
        }

        /// <summary>
        /// 添加组件
        /// </summary>
        /// <param name="components">Components.</param>
        public void AddComponents(IComponents components)
        {
            if (components == null)
            {
                return;
            }

            components.OnAdd();
            components.Host = this;

            components_maping.Add(components.TypeName, components);
            if (components.ComponentsType == ComponentsType.Loigc)
            {
                update_list.Add(components);
            }
        }

        /// <summary>
        /// 添加组件列表
        /// </summary>
        /// <param name="components"></param>
        public void AddComponentsRange(IEnumerable<IComponents> components)
        {
            foreach (var item in components ?? new List<IComponents>())
            {
                AddComponents(item);
            }
        }

        /// <summary>
        /// 根据名称获取组件
        /// </summary>
        /// <param name="typename"></param>
        /// <returns></returns>
        public IComponents GetComponents(string typename)
        {
            if (components_maping.ContainsKey(typename))
            {
                return components_maping[typename];
            }

            return null;
        }

        /// <summary>
        /// 获取对应的组件
        /// </summary>
        /// <returns>The components.</returns>
        /// <param name="typename">Typename.</param>
        /// <typeparam name="T">The 1st type parameter.</typeparam>
        public T GetComponents<T>(string typename) where T : IComponents
        {
            if (components_maping.ContainsKey(typename))
            {
                var item = components_maping[typename];
                return (T)item;
            }
            else
            {
                return default(T);
            }
        }

        /// <summary>
        /// Gets all components.
        /// </summary>
        /// <returns>The all components.</returns>
        public IEnumerable<IComponents> GetAllComponents()
        {
            return components_maping.Values;
        }

        /// <summary>
        /// 清理全部
        /// </summary>
        public void ClearAll()
        {
            foreach (var item in components_maping)
            {
                item.Value.OnRemove();
            }
            components_maping.Clear();

            foreach (var item in update_list)
            {
                item.OnRemove();
            }
            update_list.Clear();
        }
    }
}
